﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace OnWork.DataCenter.BLL.Base.Dto
{
    /// <summary>
    /// 分页查询配置
    /// </summary>
    public class BaseQueryPageInput
    {
        /// <summary>
        /// 每页数据数量 默认 20 行
        /// </summary>
        internal const int DefaultPageItems = 20;

        /// <summary>
        /// 获得/设置 查询关键字
        /// </summary>
        public string SearchText { get; set; }

        /// <summary>
        /// 获得/设置 搜索条件集合
        /// </summary>
        public List<List<BaseFilterKeyValue>> Searchs { get; set; } = new List<List<BaseFilterKeyValue>>();

        /// <summary>
        /// 获得/设置 排序字段名称
        /// </summary>
        public string SortName { get; set; }

        /// <summary>
        /// 获得/设置 排序方式
        /// </summary>
        public BaseSortOrder SortOrder { get; set; }

        /// <summary>
        /// 获得/设置 过滤条件集合
        /// </summary>
        public List<List<BaseFilterKeyValue>> Filters { get; set; } = new List<List<BaseFilterKeyValue>>();

        /// <summary>
        /// 获得/设置 搜索条件绑定模型
        /// </summary>
        public object SearchModel { get; set; }

        /// <summary>
        /// 获得/设置 当前页码 首页为 第一页
        /// </summary>
        /// <example>1</example>
        public int PageIndex { get; set; } = 1;

        /// <summary>
        /// 获得/设置 每页条目数量
        /// </summary>
        /// <example>20</example>
        public int PageItems { get; set; } = DefaultPageItems;

        /// <summary>
        /// 获得/设置 是否是分页查询 默认为 false
        /// </summary>
        public bool IsPage { get; set; }
    }

    /// <summary>
    /// 动态表达式语句
    /// </summary>
    public class DynamicStr
    {
        /// <summary>
        /// 条件语句
        /// </summary>
        public string Where { get; set; }

        /// <summary>
        /// 排序语句
        /// </summary>
        public string Order { get; set; }
    }

    /// <summary>
    /// 扩展
    /// </summary>
    public static class BaseQueryPageInputExtend
    {
        /// <summary>
        /// 转换到查询语句
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static DynamicStr ToQuerySQL<T>(this BaseQueryPageInput input)
        {
            DynamicStr dynamicStr = new DynamicStr();

            //反射获取所有属性
            var props = typeof(T).GetProperties();

            //搜索条件判断
            string whereSearchsStr = "";
            if (input.Searchs != null && input.Searchs.Count > 0)
            {
                whereSearchsStr = GetwhereStr(input.Searchs, props, "or");
            }

            //过滤条件
            string whereFilterStr = "";
            if (input.Filters != null)
            {
                whereFilterStr = GetwhereStr(input.Filters, props);
            }

            string orderStr = "";
            if (!string.IsNullOrEmpty(input.SortName) && input.SortOrder != BaseSortOrder.Unset)
            {
                //查询属性是否存在
                var p = props.Where(x => x.Name == input.SortName).FirstOrDefault();
                if (p != null)
                {
                    if (input.SortOrder == BaseSortOrder.Asc)
                    {
                        orderStr = $"{input.SortName} ";
                    }
                    else if (input.SortOrder == BaseSortOrder.Desc)
                    {
                        orderStr = $"{input.SortName} desc";
                    }
                }
            }
            //查询条件
            string whereAll = "";
            if (!string.IsNullOrEmpty(whereSearchsStr))
            {
                whereAll += whereSearchsStr;
            }
            if (!string.IsNullOrEmpty(whereFilterStr))
            {
                if (whereAll.Length > 0)
                {
                    whereAll = $"({whereAll}) and ({whereFilterStr})";
                }
                else
                {
                    whereAll += whereFilterStr;
                }
            }

            dynamicStr.Where = whereAll;

            //排序条件
            if (!string.IsNullOrEmpty(orderStr))
            {
                dynamicStr.Order = orderStr;
            }
            return dynamicStr;
        }

        /// <summary>
        /// 根据对象属性 获取字符串条件
        /// </summary>
        /// <param name="baseFilterKeyValues"></param>
        /// <param name="props"></param>
        /// <param name="logicDefault"> 查询列表中的默认关系 默认为and</param>
        /// <returns></returns>
        private static string GetwhereStr(List<List<BaseFilterKeyValue>> baseFilterKeyValues, PropertyInfo[] props, string logicDefault = "and")
        {
            string whereAllSearchsStr = "";
            foreach (var itemList in baseFilterKeyValues)
            {
                string whereSearchsStr = "";
                foreach (var item in itemList)
                {
                    //查询属性是否存在
                    var p = props.Where(x => x.Name == item.FieldKey).FirstOrDefault();
                    if (p != null)
                    {
                        string valStr = "";
                        if (p.PropertyType == typeof(string))
                        {
                            valStr = $"'{item.FieldValue}'";
                        }else if(p.PropertyType.BaseType == typeof(Enum)) //类型为JSOn的转换条件书数字
                        {
                            valStr =  Enum.Parse(p.PropertyType, item.FieldValue).GetHashCode().ToString();
                            
                            // valStr = item.FieldValue;
                        }
                        else
                        {
                            valStr = item.FieldValue;
                        }
                        string opStr = "";
                        switch (item.FilterAction)
                        {
                            case BaseFilterAction.Equal:
                                opStr = $"{item.FieldKey} == {valStr}";
                                break;

                            case BaseFilterAction.NotEqual:
                                opStr = $"{item.FieldKey} != {valStr}";
                                break;

                            case BaseFilterAction.GreaterThan:
                                opStr = $"{item.FieldKey} > {valStr}";
                                break;

                            case BaseFilterAction.GreaterThanOrEqual:
                                opStr = $"{item.FieldKey} >= {valStr}";
                                break;

                            case BaseFilterAction.LessThan:
                                opStr = $"{item.FieldKey} < {valStr}";
                                break;

                            case BaseFilterAction.LessThanOrEqual:
                                opStr = $"{item.FieldKey} >= {valStr}";
                                break;

                            case BaseFilterAction.Contains:
                                //opStr = $"{item.FieldKey}.Contains({valStr})";
                                opStr = $"{item.FieldKey} like '%{item.FieldValue}%'";
                                break;
                            case BaseFilterAction.NotContains:
                                opStr = $"{item.FieldKey} not like '%{item.FieldValue}%'";
                                break;

                            case BaseFilterAction.CustomPredicate:
                                break;

                            default:
                                break;
                        }

                        //关系字符串
                        string logicStr = "";

                        logicStr = item.FilterLogic switch
                        {
                            BaseFilterLogic.And => "and",
                            BaseFilterLogic.Or => "or",
                            _ => "or",
                        };

                        //如果是空的则添加直接添加
                        if (string.IsNullOrEmpty(whereSearchsStr))
                        {
                            whereSearchsStr = opStr;
                        }
                        else
                        {
                            whereSearchsStr += $" {logicStr} {opStr} ";
                        }
                    }
                }
                //不等于空的时候增加
                if (!string.IsNullOrEmpty(whereSearchsStr))
                {
                    if (string.IsNullOrEmpty(whereAllSearchsStr))
                    {
                        whereAllSearchsStr = $"({whereSearchsStr})";
                    }
                    else
                    {
                        //whereAllSearchsStr += $" and ({whereSearchsStr})";
                        //查询条件为0r 过滤条件为 and 
                        whereAllSearchsStr += $" {logicDefault} ({whereSearchsStr})";
                    }
                }
            }
            return whereAllSearchsStr;
        }
    }

    /// <summary>
    /// 关系运算符
    /// </summary>
    public enum BaseFilterAction
    {
        /// <summary>
        /// 等于
        /// </summary>
        Equal,

        /// <summary>
        /// 不等于
        /// </summary>
        NotEqual,

        /// <summary>
        /// 大于
        /// </summary>
        GreaterThan,

        /// <summary>
        /// 大于等于
        /// </summary>
        GreaterThanOrEqual,

        /// <summary>
        /// 小于
        /// </summary>
        LessThan,

        /// <summary>
        /// 小于等于
        /// </summary>
        LessThanOrEqual,

        /// <summary>
        /// 包含
        /// </summary>
        Contains,

        /// <summary>
        /// 不包含
        /// </summary>
        NotContains,

        /// <summary>
        /// 自定义条件
        /// </summary>
        CustomPredicate
    }

    /// <summary>
    /// 逻辑运算符
    /// </summary>
    public enum BaseFilterLogic
    {
        /// <summary>
        /// 并且
        /// </summary>
        And,

        /// <summary>
        /// 或者
        /// </summary>
        Or
    }

    /// <summary>
    /// 排序
    /// </summary>
    public enum BaseSortOrder
    {
        /// <summary>
        /// 未设置
        /// </summary>
        Unset,

        /// <summary>
        /// 升序 0-9 A-Z
        /// </summary>
        Asc,

        /// <summary>
        /// 降序 9-0 Z-A
        /// </summary>
        Desc,
    }

    /// <summary>
    /// Filter 过滤条件项目
    /// </summary>
    public class BaseFilterKeyValue
    {
        /// <summary>
        /// 获得/设置 Filter 项字段名称
        /// </summary>
        public string FieldKey { get; set; }

        /// <summary>
        /// 获得/设置 Filter 项字段值
        /// </summary>
        public string FieldValue { get; set; }

        /// <summary>
        /// 获得/设置 Filter 项与其他 Filter 逻辑关系
        /// </summary>
        public BaseFilterLogic FilterLogic { get; set; }

        /// <summary>
        /// 获得/设置 Filter 条件行为
        /// </summary>
        public BaseFilterAction FilterAction { get; set; }
    }
}
